package com.ylsk.check.service.impl;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSONObject;
import com.ylsk.check.domain.JeevesReport;
import com.ylsk.check.domain.ReportInfo;
import com.ylsk.check.domain.dto.EntryReportDTO;
import com.ylsk.check.domain.dto.MsgTemplateDTO;
import com.ylsk.check.domain.dto.SendMsgArgsDTO;
import com.ylsk.check.domain.emum.BasicInfoTemplateEnum;
import com.ylsk.check.domain.emum.ConstructionStatusEnum;
import com.ylsk.check.domain.emum.MsgTemplateEnum;
import com.ylsk.check.domain.so.EntryReportSO;
import com.ylsk.check.domain.vo.EntryReportVO;
import com.ylsk.check.mapper.JeevesReportMapper;
import com.ylsk.check.mapper.ReportInfoMapper;
import com.ylsk.check.task.RetrieveUnexecutedTask;
import com.ylsk.check.util.SendMsg;
import com.ylsk.common.annotation.DataScope;
import com.ylsk.common.config.SnowIdConfig;
import com.ylsk.common.core.domain.entity.SysUser;
import com.ylsk.common.exception.ServiceException;
import com.ylsk.common.utils.*;
import com.ylsk.system.domain.FileSimple;
import com.ylsk.system.helper.FileHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ylsk.check.mapper.EntryReportMapper;
import com.ylsk.check.domain.EntryReport;
import com.ylsk.check.service.IEntryReportService;
import org.springframework.transaction.annotation.Transactional;


/**
 * 进场上报Service业务层处理
 *
 * @author yangsy
 * @date 2023-12-20
 */
@Service
public class EntryReportServiceImpl implements IEntryReportService
{
    private static final Logger log = LoggerFactory.getLogger(EntryReportServiceImpl.class);
    @Autowired
    private EntryReportMapper entryReportMapper;

    @Autowired
    private SnowIdConfig snowIdConfig;

    @Autowired
    private ReportInfoHelper helper;

    @Autowired
    private FileHelper fileHelper;

    @Autowired
    private ReportInfoMapper reportInfoMapper;

    @Autowired
    private JeevesReportMapper jeevesReportMapper;

    @Autowired
    private SerialNoUtils serialNoUtils;

    /**
     * 查询进场上报
     *
     * @param entryReportId 进场上报主键
     * @return 进场上报
     */
    @Override
    public EntryReportVO selectEntryReportByEntryReportId(Long entryReportId)
    {
        EntryReportVO entryReportVO = entryReportMapper.selectEntryReportByEntryReportId(entryReportId);

        Long entryFileId = entryReportVO.getEntryFileId();
        List<FileSimple> entryFile = fileHelper.getFileByBusinessId(entryFileId);
        entryReportVO.setEntryFile(entryFile);

        return entryReportVO;
    }

    /**
     * 查询进场上报列表
     *
     * @param entryReportSO 进场上报
     * @return 进场上报
     */
    @Override
    @DataScope(deptAlias = "sd",userAlias = "su")
    public List<EntryReportVO> selectEntryReportList(EntryReportSO entryReportSO)
    {
        return entryReportMapper.selectEntryReportList(entryReportSO);
    }

    /**
     * 新增进场上报
     *
     * @param entryReportDTO 进场上报
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertEntryReport(EntryReportDTO entryReportDTO)
    {
        EntryReport entryReport = new EntryReport();
        BeanUtils.copyProperties(entryReportDTO,entryReport);

        final Long reportInfoId = entryReport.getReportInfoId();
        ReportInfo reportInfo = helper.getReportInfo(reportInfoId);

        helper.checkData(reportInfo,new Generic<>(entryReportDTO));

        entryReport.setDeptId(reportInfo.getDeptId());
        entryReport.setReviewedBy(reportInfo.getReviewedBy());
        //  附件信息
        String entryFile = entryReportDTO.getEntryFile();
        long entryFileId = snowIdConfig.getSnowId();
        if(StringUtils.isNotEmpty(entryFile)){
            fileHelper.saveBusinessFileData(entryFile,entryFileId);
        }
        final Long entryReportId = snowIdConfig.getSnowId();
        entryReport.setEntryReportId(entryReportId);
        entryReport.setEntryFileId(entryFileId);

        //设置报备信息 施工状态
        //是否占道  0未占道  1占道
        Integer isJeeves = entryReport.getIsJeeves();
        //  施工状态  默认为非占道施工
        ConstructionStatusEnum constructionStatusEnum = ConstructionStatusEnum.CONSTRUCTION;
        if(1 == isJeeves){
            //设置状态 如果当前时间 大于占道开始日期 则设置为 为占道施工 反之设置为非占道施工
            if(new Date().after(entryReportDTO.getJeevesStartDate())){
                constructionStatusEnum = ConstructionStatusEnum.ROAD_CONSTRUCTION;
            }
            //占道施工 需要把占道信息写入到占道报备信息中
            JeevesReport jeevesReport = new JeevesReport();
            Long jeevesReportId = snowIdConfig.getSnowId();
            BeanUtils.copyProperties(entryReportDTO,jeevesReport);
            jeevesReport.setJeevesReportId(jeevesReportId);
            jeevesReport.setJeevesNum(serialNoUtils.generateSerialNo(SerialNoUtils.ZDBB_ORDER));
            jeevesReport.setDeptId(reportInfo.getDeptId());//设置部门id
            jeevesReport.setReviewedBy(reportInfo.getReviewedBy());//设置审核人
            jeevesReport.setEntryReportId(entryReportId);//设置进场上报id
            jeevesReportMapper.insert(jeevesReport);
        }
        //更新施工状态
        helper.updateReportConstructionStatus(reportInfo,constructionStatusEnum);
        //发送消息通知
        List<Long> toUser = helper.getDeptLeader(reportInfo.getDeptId()).stream().map(SysUser::getUserId).collect(Collectors.toList());
        MsgTemplateDTO msgTemplateDTO = new MsgTemplateDTO(MsgTemplateEnum.TEMPLATE_JCSB,SecurityUtils.getUserId(), toUser);
        String p1 = SecurityUtils.getLoginUser().getUser().getNickName();
        String p2 = DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:ss");
        String p3 = reportInfo.getProjectName();
        String p4 = DateUtils.dateTime(entryReport.getEntryTime());
        helper.saveMsg(msgTemplateDTO,p1,p2,p3,p4);

        //发送短信息
        for (int i = 0; i < toUser.size(); i++) {
            SysUser sysUser = helper.getUserInfo(toUser.get(i));
            SendMsgArgsDTO sendMsgArgsDTO = new SendMsgArgsDTO();
            sendMsgArgsDTO.setTellPhone(sysUser.getPhonenumber());
            sendMsgArgsDTO.setProject(SendMsgArgsDTO.PROJECT_SGJC);
            JSONObject vars = new JSONObject();
            vars.put("project",p3);
            sendMsgArgsDTO.setVars(vars);
            log.info("发送人员电话号码={},所属大队={},参数内容={}", sysUser.getPhonenumber(),sysUser.getDept().getDeptName(),vars.toString());
            SendMsg.toSend(helper.enableSendMsg(),sendMsgArgsDTO);
        }
        //生成检查单
        helper.saveTask(reportInfoId,constructionStatusEnum.getCode(), BasicInfoTemplateEnum.INS_ENTRY_REPORT.getTbName(),entryReportId,entryReportDTO.getEntryTime(),reportInfo.getDeptId());
        return entryReportMapper.insert(entryReport);
    }

    /**
     * 修改进场上报
     *
     * @param entryReportDTO 进场上报
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateEntryReport(EntryReportDTO entryReportDTO)
    {
        Long entryReportId = entryReportDTO.getEntryReportId();
        if(null == entryReportId){
            throw new ServiceException("进场上报id不能为空!");
        }
        EntryReport entryReport = new EntryReport();
        BeanUtils.copyProperties(entryReportDTO,entryReport);

        String entryFile = entryReportDTO.getEntryFile();
        EntryReport _entryReport = entryReportMapper.selectById(entryReportId);
        fileHelper.updateBusinessFileData(entryFile,_entryReport.getEntryFileId());
        return entryReportMapper.updateById(entryReport);
    }

    /**
     * 批量删除进场上报
     *
     * @param entryReportIds 需要删除的进场上报主键
     * @return 结果
     */
    @Override
    public int deleteEntryReportByEntryReportIds(Long[] entryReportIds)
    {
        return entryReportMapper.deleteEntryReportByEntryReportIds(entryReportIds);
    }

    /**
     * 删除进场上报信息
     *
     * @param entryReportId 进场上报主键
     * @return 结果
     */
    @Override
    public int deleteEntryReportByEntryReportId(Long entryReportId)
    {
        return entryReportMapper.deleteEntryReportByEntryReportId(entryReportId);
    }
}
